package com.school.fuyuan.common.util;

import com.school.fuyuan.common.message.RequestHead;
import com.school.fuyuan.common.message.RequestMsg;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;

/**
 * @author zrhong
 * @version 1.0
 * @date 2019/3/3 20:43
 * @description
 */
public abstract class RequestUtils {

    private static final String REQUEST_MSG_KEY = "requestMsg";

    /**
     * 动态获取request的封装，不想使用注入时可使用此方法
     *
     * @return HttpServletRequest
     */
    public static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
    }

    public static <T> void setRequestAttr(String key, T obj) {
        getRequest().setAttribute(key, obj);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getRequestAttr(String key) {
        return (T) getRequest().getAttribute(key);
    }

    /**
     * 获取暂存在request中的RequestMsg，使用前请确保已经暂存有RequestMsg
     *
     * @param <T> 暂存的RequestMsg中数据对象的具体类型
     * @return RequestMsg&lt;T>
     */
    @SuppressWarnings("unchecked")
    public static <T> RequestMsg<T> getRequestMsg() {
        return (RequestMsg<T>) getRequest().getAttribute(REQUEST_MSG_KEY);
    }

    /**
     * 暂存RequestMsg到request中，需要时再调用
     *
     * @param requestMsg 请求参数
     * @param <T>        数据实体对象或数据Map对象
     */
    public static <T> void cacheRequestMsg(RequestMsg<T> requestMsg) {
        getRequest().setAttribute(REQUEST_MSG_KEY, requestMsg);
    }

    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？
     * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
     * 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100
     * 用户真实IP为： 192.168.1.110
     *
     * @return String ip
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")) {
                //根据网卡取本机配置的IP
                InetAddress inetAddress = InetAddress.getLoopbackAddress();
                ip = inetAddress.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.split("\\.").length > 4) {
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return ip;
    }

}
